package com.huawei.codearts.tools.utils;


import com.huawei.codearts.tools.exception.CustomException;
import com.huawei.codearts.tools.exception.ServiceException;
import com.huawei.codearts.tools.validated.StatusEnum;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;

@Slf4j
public class ResultUtils {
    /**
     * 封装成功响应的方法
     * @param data 响应数据
     * @return reponse
     * @param <T> 响应数据类型
     */
    public static <T> ResultResponse<T> success(T data) {
        return success(StatusEnum.SUCCESS.code, data);
    }

    public static <T> ResultResponse<T> success() {
        return success(StatusEnum.SUCCESS.code, (T) new HashMap<>());
    }

    public static <T> ResultResponse<T> success(int code, T data) {
        return response(code, StatusEnum.SUCCESS.message, data);
    }

    public static <T> ResultResponse<T> ok(int code, T data) {
        return response(code, StatusEnum.SUCCESS.message, data);
    }

    public static <T> ResultResponse<T> success(int code, String msg) {
        return response(code, msg, (T) new HashMap<>());
    }

    public static <T> ResultResponse<T> response(int code, String msg, T data) {
        return result(code, msg, data);
    }

    private static <T> ResultResponse<T> result(int code, String msg, T data) {
        ResultResponse<T> response = new ResultResponse<>();
        response.setCode(code);
        response.setMsg(msg);
        response.setData(data==null? (T) new HashMap<>() :data);
        return response;
    }


    /** 封装error的响应 */
    public static <T> ResultResponse<T> error(StatusEnum statusEnum) {
        return error(statusEnum, statusEnum.message);
    }

    public static <T> ResultResponse<T> error(String message) {
        return error(StatusEnum.ERROR, message);
    }

    /** 封装error的响应  可自定义错误信息 */
    public static <T> ResultResponse<T> error(StatusEnum statusEnum, String errorMsg) {
        return error(statusEnum.code, errorMsg);
    }

    public static <T> ResultResponse<T> error(int code, String message) {
        return result(code, message, (T) new HashMap<>());
    }

    /** exception 输出 */
    public static <T> ResultResponse<T> exception(Throwable ex) {
        logInfo(ex);
        return responseException(StatusEnum.SERVICE_ERROR, StatusEnum.SERVICE_ERROR.message);
    }

    /** runtimeException 输出 */
    public static <T> ResultResponse<T> runtimeException(Throwable ex) {
        logInfo(ex);
        return responseException(StatusEnum.ERROR, ex.getMessage());
    }

    /** ServiceException 输出 */
    public static <T> ResultResponse<T> customException(ServiceException ex) {
        logInfo(ex);
        return responseException(ex.getStatus(), ex.getMessage());
    }

    /** CustomException 输出 */
    public static <T> ResultResponse<T> customException(CustomException ex) {
        logInfo(ex);
        String message = ex.getMessage();
        return error(ex.getCode(), message == null ? StatusEnum.ERROR.message : message);
    }

    /** responseException 输出 */
    private static <T> ResultResponse<T> responseException(StatusEnum statusEnum, String message) {
        return error(statusEnum, message == null ? StatusEnum.ERROR.message : message);
    }

    /** log info */
    public static void logInfo(Throwable e) {
        // 获取异常类名和异常信息
        String exceptionName = e.getClass().getName();
        String message = e.getMessage();

        // 获取异常栈轨迹中的文件名和方法名
        StackTraceElement[] stackTrace = e.getStackTrace();
        String fileName = stackTrace[0].getFileName();
        String methodName = stackTrace[0].getMethodName();
        String className = stackTrace[0].getClassName();
        int lineNumber = stackTrace[0].getLineNumber();

        // 记录日志
        log.info("[error]:{}, [path]:{}, [line]:({}:{}), message:{}",
                exceptionName,
                className+"."+methodName+"()",
                fileName,
                lineNumber,
                message);
    }

}
